package org.linlinjava.litemall.db.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.linlinjava.litemall.db.dao.CouponMapper;
import org.linlinjava.litemall.db.dao.CouponUserMapper;
import org.linlinjava.litemall.db.models.Coupon;
import org.linlinjava.litemall.db.models.CouponUser;
import org.linlinjava.litemall.db.service.CouponService;
import org.linlinjava.litemall.db.util.CouponConstant;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon>
        implements CouponService {
    @Resource
    CouponUserMapper couponUserMapper;

    @Override
    public IPage<Coupon> queryList(int offset, int limit) {
        Page<Coupon> page = new Page<>(offset, limit);
        return baseMapper.selectPage(page, new LambdaQueryWrapper<Coupon>().orderByDesc(Coupon::getAddTime));
    }

    @Override
    public IPage<Coupon> queryAvailableList(Integer userId, int offset, int limit) {
        assert userId != null;
        // 过滤掉登录账号已经领取过的coupon
        QueryWrapper<CouponUser> userQuery = new QueryWrapper<>();
        userQuery.eq("user_id", userId);
        List<CouponUser> used = couponUserMapper.selectList(userQuery);

        QueryWrapper<Coupon> query = new QueryWrapper<>();
        Page<Coupon> page = new Page<>(offset, limit);
        if(used!=null && !used.isEmpty()){
            query.notIn("id", used.stream().map(CouponUser::getCouponId).collect(Collectors.toList()));
        }
        query.orderByDesc("add_time");

        return baseMapper.selectPage(page, query);
    }

    @Override
    public Coupon findByCode(String code) {
        QueryWrapper<Coupon> query = new QueryWrapper<>();
        query.eq("code", code);
        query.eq("type",CouponConstant.TYPE_CODE).eq("status", CouponConstant.STATUS_NORMAL);
        List<Coupon> couponList =  baseMapper.selectList(query);
        if(couponList.size() > 1){
            throw new RuntimeException("同一个号查询到多条记录");
        }
        else if(couponList.size() == 0){
            return null;
        }
        else {
            return couponList.get(0);
        }
    }

    /**
     * 查询新用户注册优惠券
     *
     * @return
     */
    @Override
    public List<Coupon> queryRegister() {
        QueryWrapper<Coupon> query = new QueryWrapper<>();
        query.eq("type",CouponConstant.TYPE_REGISTER).eq("status", CouponConstant.STATUS_NORMAL);
        return baseMapper.selectList(query);
    }

    @Override
    public IPage<Coupon> querySelective(String name, Short type, Short status, Integer pageNo, Integer pageSize) {
        QueryWrapper<Coupon> query = new QueryWrapper<>();
        Page<Coupon> page = new Page<>(pageNo, pageSize);
        query.like(!StringUtils.isEmpty(name), "name", name);
        query.eq(type != null, "type", type);
        query.eq(status != null, "status", status);
        return baseMapper.selectPage(page, query);
    }

    private String getRandomNum(Integer num) {
        String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 生成优惠码
     *
     * @return 可使用优惠码
     */
    @Override
    public String generateCode() {
        String code = getRandomNum(8);
        while(findByCode(code) != null){
            code = getRandomNum(8);
        }
        return code;
    }

    /**
     * 查询过期的优惠券:
     * 注意：如果timeType=0, 即基于领取时间有效期的优惠券，则优惠券不会过期
     *
     * @return
     */
    @Override
    public List<Coupon> queryExpired() {
        QueryWrapper<Coupon> query = new QueryWrapper<>();
        query.eq("time_type",CouponConstant.TIME_TYPE_TIME).eq("status", CouponConstant.STATUS_NORMAL);
        query.le("end_time", LocalDateTime.now());
        return baseMapper.selectList(query);
    }
}
